package com.game.util;

import java.io.ByteArrayInputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.game.pojo.message.Article;
import com.game.pojo.message.BaseMessage;
import com.game.pojo.message.NewsMessage;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

/**
 *	消息工具类
 * 
 * @author chai
 */
public class MessageUtils {
	// 请求消息类型：文本
	public static final String REQ_MESSAGE_TYPE_TEXT = "text";
	// 请求消息类型：图片
	public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
	// 请求消息类型：音频
	public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
	// 请求消息类型：视频
	public static final String REQ_MESSAGE_TYPE_VIDEO = "video";
	// 请求消息类型：小视频视频
		public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";
	// 请求消息类型：位置
	public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
	// 请求消息类型：链接
	public static final String REQ_MESSAGE_TYPE_LINK = "link";

	// 请求消息类型：事件推送
	public static final String REQ_MESSAGE_TYPE_EVENT = "event";

	// 事件类型：订阅
	public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
	// 事件类型：取消订阅
	public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
	// 事件类型：关注用户扫描带参数二维码
	public static final String EVENT_TYPE_SCAN = "scan";
	// 事件类型：上报地理位置
	public static final String EVENT_TYPE_LOCATION = "LOCATION";
	// 事件类型：点击自定义菜单
	public static final String EVENT_TYPE_CLICK = "CLICK";

	// 响应消息类型：文本
	public static final String RESP_MESSAGE_TYPE_TEXT = "text";
	// 响应消息类型：图片
	public static final String RESP_MESSAGE_TYPE_IMAGE = "image";
	// 响应消息类型：音频
	public static final String RESP_MESSAGE_TYPE_VOICE = "voice";
	// 响应消息类型：视频
	public static final String RESP_MESSAGE_TYPE_VIDEO = "video";
	// 响应消息类型：音乐
	public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
	// 响应消息类型：图文消息
	public static final String RESP_MESSAGE_TYPE_NEWS = "news";
	/**
	 * 解析微信服务器发来的xml
	 * @param xml
	 * @return
	 * @throws DocumentException
	 */
	public static Map<String,String> parseXML(String xml) throws DocumentException{
		//将解析结果保存为map
		Map<String,String> map = new HashMap<>();
		//使用dom4j解析xml
		SAXReader reader = new SAXReader();
		Document document = reader.read(new ByteArrayInputStream(xml.getBytes()));
		//获取根节点
		Element rootElement = document.getRootElement();
		//获取根节点的子节点集合
		List<Element> elements = rootElement.elements();
		//遍历子节点，存入map
		for (Element e : elements) {
			map.put(e.getName(), e.getText());
		}
		return map;
	}
	/**
	 * 扩展XStream以使其支持CDATA，如果不支持CDATA，返回的消息中含有
	 * <>&这些符号时，就会出错
	 */
	private static XStream xStream = new XStream(new XppDriver()){
		public HierarchicalStreamWriter createWriter(Writer out){
			return new PrettyPrintWriter(out){
				//对所有xml节点都添加CDATA标记
				boolean cdata = true;
				
				@Override
				public void startNode(String name, Class clazz) {
					super.startNode(name, clazz);
				}
				
				@Override
				protected void writeText(QuickWriter writer, String text) {
					if(cdata){
						writer.write("<![CDATA[");
						writer.write(text);
						writer.write("]]>");
					}else{
						writer.write(text);
					}
				}
			};
		}
	};
	
	/**
	 * 将消息对象转换为xml
	 * @param baseMessage
	 * @return
	 */
	public static String messageToXML(BaseMessage baseMessage){
		if(baseMessage instanceof NewsMessage){
			xStream.alias("xml", baseMessage.getClass());
			xStream.alias("item", new Article().getClass());
			return xStream.toXML(baseMessage);
		}else{
			xStream.alias("xml", baseMessage.getClass());
			return xStream.toXML(baseMessage);
		}
	}
}	